package cn.openea.perpartner.common.redis.service;

import org.redisson.api.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * Redisson
 */
@Service("redissonService")
public class RedissonService {

    private static final String LOCK_TITLE = "redisLock_";

    @Resource
    private RedissonClient redissonClient;

    public void getRedissonClient() throws IOException {
        redissonClient.getConfig();
    }

    /**
     * `
     * 获取字符串对象
     *
     * @param objectName
     * @return
     */
    public <T> RBucket<T> getRBucket(String objectName) {
        return redissonClient.getBucket(objectName);
    }

    /**
     * 获取Map对象
     *
     * @param objectName
     * @return
     */
    public <K, V> RMap<K, V> getRMap(String objectName) {
        return redissonClient.getMap(objectName);
    }

    /**
     * 获取有序集合
     *
     * @param objectName
     * @return
     */
    public <V> RSortedSet<V> getRSortedSet(String objectName) {
        return redissonClient.getSortedSet(objectName);
    }

    /**
     * 获取集合
     *
     * @param objectName
     * @return
     */
    public <V> RSet<V> getRSet(String objectName) {
        return redissonClient.getSet(objectName);
    }

    /**
     * 获取列表
     *
     * @param objectName
     * @return
     */
    public <V> RList<V> getRList(String objectName) {
        return redissonClient.getList(objectName);
    }

    /**
     * 获取队列
     *
     * @param objectName
     * @return
     */
    public <V> RQueue<V> getRQueue(String objectName) {
        return redissonClient.getQueue(objectName);
    }

    /**
     * 获取双端队列
     *
     * @param objectName
     * @return
     */
    public <V> RDeque<V> getRDeque(String objectName) {
        return redissonClient.getDeque(objectName);
    }

    /**
     * 获取锁
     *
     * @param objectName
     * @return
     */
    public RLock getRLock(String objectName) {
        return redissonClient.getLock(objectName);
    }

    public boolean lockSeconds(String lockName, Integer waitTime, Integer timeOutSecond) {
        try {
            String key = LOCK_TITLE + lockName;
            RLock lock = this.getRLock(key);
            //lock提供带timeout参数，timeout结束强制解锁，防止死锁
            //先尝试在超时时间内获取锁，如果没有获取到，此时如果等待时间还有剩余进入循环不断取尝试获取锁 直到时间结束退出  循环中是订阅，时间结束取消订阅
            return lock.tryLock(waitTime, timeOutSecond, TimeUnit.SECONDS);
        } catch (InterruptedException e) {

        } catch (Exception e) {

        }
        return false;
    }


    public void unlock(String lockName) {
        try {
            String key = LOCK_TITLE + lockName;
            RLock lock = this.getRLock(key);
            if (lock.isHeldByCurrentThread() && lock.isLocked()) {
                lock.unlock();
            }
        } catch (Exception e) {

        }

    }


    /**
     * 获取读写锁
     *
     * @param objectName
     * @return
     */
    public RReadWriteLock getRWLock(String objectName) {
        return redissonClient.getReadWriteLock(objectName);
    }

    /**
     * 获取原子数
     *
     * @param objectName
     * @return
     */
    public RAtomicLong getRAtomicLong(String objectName) {
        return redissonClient.getAtomicLong(objectName);
    }

    /**
     * 获取记数锁
     *
     * @param objectName
     * @return
     */
    public RCountDownLatch getRCountDownLatch(String objectName) {
        return redissonClient.getCountDownLatch(objectName);
    }

    /**
     * 获取消息的Topic
     *
     * @param objectName
     * @return
     */
    public RTopic getRTopic(String objectName) {
        return redissonClient.getTopic(objectName);
    }
}
